/** @file dip.c 
 * Digital Image Processing Implementationen
 * 
 * @author Daniel Kummer, Sebastian Kummer
 * @date Donnerstag, Dezember 12, 2007
 * @version 1.0
 */

#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>

#include "lcv-structs.h"
#include "lcv-config.h"
#include "dip.h"
#include "log.h"


lcv_picture lcv_clone_picture(const lcv_picture* pic)
{
	lcv_picture res_pic;
	
	res_pic.type = pic->type;
	res_pic.height = pic->height;
	res_pic.width = pic->width;
	res_pic.length = pic->length;
	res_pic.data = (unsigned char *)malloc(pic->length);
	(void)memcpy(res_pic.data, pic->data, pic->length);		
	return res_pic;							   
}

void lcv_free_picture(lcv_picture* pic)
{
	free(pic->data);	
}

lcv_picture lcv_invert(const lcv_picture* pic)
{
	lcv_picture res_pic;
	int i;
	
	res_pic.type = pic->type;
	res_pic.height = pic->height;
	res_pic.width = pic->width;
	res_pic.length = pic->length;
	res_pic.data = (unsigned char *)malloc(pic->length);
	
	
	for (i=0; i<res_pic.length; i++) {
		res_pic.data[i] = 255 - pic->data[i];
	}
	
	return res_pic;
}

lcv_picture lcv_reverse(const lcv_picture* pic)
{
	lcv_picture res_pic;
	char * error_msg;
	int i;
	
	res_pic.type = pic->type;
	res_pic.height = pic->height;
	res_pic.width = pic->width;
	res_pic.length = pic->length;
	res_pic.data = (unsigned char *)malloc(pic->length);
	
	if (res_pic.type == IMG_BGR) {
		for (i=0; i<res_pic.length; i = i+3) {
			res_pic.data[res_pic.length - 1 - i - 2] = pic->data[i];
			res_pic.data[res_pic.length - 1 - i - 1] = pic->data[i+1];
			res_pic.data[res_pic.length - 1 - i] = pic->data[i+2];
		}
	} else {
		for (i=0; i<res_pic.length; i++) {
			res_pic.data[res_pic.length - 1 - i] = pic->data[i];
		}
	}
	return res_pic;
}

unsigned int lcv_avg_value(const lcv_picture* pic)
{
	int i;
	int value = 0;
	
	for (i=0; i < pic->length; i++) {
		value += pic->data[i];
	}
	
	return (value / i);
}

lcv_picture lcv_rgb2gray(const lcv_picture* pic)
{
	lcv_picture res_pic;
	int 		gray_value;
	int i;	
	
	res_pic.height = pic->height;
	res_pic.width = pic->width;	
	res_pic.type = IMG_GRAYSCALE;
	
	if (pic->type == IMG_BGR) {
		res_pic.length = pic->length / 3;
		res_pic.data = (unsigned char*)malloc(res_pic.length);
		
		for (i = 0; i < pic->length ; i = i+3) {			
			gray_value = (pic->data[i] + pic->data[i+1] + pic->data[i+2]) / 3;			
			res_pic.data[i/3] = gray_value;		
		}
	} else {
		res_pic.length = pic->length;
		res_pic.data = (unsigned char*)malloc(pic->length);
		(void)memcpy(res_pic.data, pic->data, pic->length);
	}
	return res_pic;
}

lcv_picture lcv_gray2rgb(const lcv_picture* pic)
{
	lcv_picture res_pic;
	int i;	
	
	res_pic.height = pic->height;
	res_pic.width = pic->width;	
	res_pic.type = IMG_BGR;
	
	if(pic->type == IMG_GRAYSCALE){
		res_pic.length = pic->length * 3;
		res_pic.data = (unsigned char*)malloc(res_pic.length);
		
		for (i = 0; i < res_pic.length ; i = i+3) {	
			res_pic.data[i] = pic->data[i/3];
			res_pic.data[i+1] = pic->data[i/3];
			res_pic.data[i+2] = pic->data[i/3];
		}
	} else {
		res_pic.length = pic->length;
		res_pic.data = (unsigned char*)malloc(pic->length);
		(void)memcpy(res_pic.data, pic->data, pic->length);
	}
	return res_pic;
}
